package com.ghh.app.monsterrush;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener;
import com.badlogic.gdx.utils.Disposable;

public abstract class WeaponActor extends Actor implements Disposable {
	public final static int			CREATING	= 1;
	public final static int			READY		= 2;
	public final static int			FLING		= 3;
	public final static int			ATTACKING	= 4;
	public final static int			DESTROYED	= 5;

	protected final static float	width		= 150f;	// actor width
	protected final static float	height		= 150f;	// actor height

	protected float					drawWidth	= 0f;		// display width
	protected float					drawHeight	= 0f;		// display height
	protected float					drawX		= 0;		// display x
	protected float					drawY		= 0;		// display y

	protected float					speedx;
	protected float					speedy;
	protected int					power;
	protected MonsterRushGame		game;
	protected int					status		= CREATING;

	protected StateAction			state_arise;
	protected StateAction			state_ready;
	protected StateAction			state_fly;
	protected StateAction			state_attack;

	protected StateAction			currentState;

	public WeaponActor(MonsterRushGame game, int power) {
		this.game = game;
		this.power = power;
		create();
		setSize(width, height);
		initState();
		currentState = state_arise;
		currentState.start();
	}
	
	protected abstract void create();
	
	private void initState() {
		state_arise = createStateCreate();
		state_ready = createStateReady();
		state_fly = createStateFly();
		state_attack = creatStateAttack();
	}

	public void onReady() {
		status = READY;
		currentState = state_ready;
		currentState.start();
		addListener(new ActorGestureListener() {
			@Override
			public void fling(InputEvent event, float velocityX, float velocityY, int button) {
				if (!isReady()) {
					return;
				}
				setSpeed(velocityX, velocityY);
				onFlingOut();
			}
		});
	}

	public void onFlingOut() {
		status = FLING;
		currentState = state_fly;
		currentState.start();
		game.onWeaponReady();
	}

	public void onAttack() {
		currentState = state_attack;
		currentState.start();
	}

	@Override
	public void draw(SpriteBatch batch, float parentAlpha) {
		currentState.act(Gdx.graphics.getDeltaTime());
		currentState.draw(batch);
		game.onUpdateWeapon(this);
	}

	public void drawFrame(SpriteBatch batch, TextureRegion frame) {
		drawWidth = getObjectWidth() * getScaleX();
		drawHeight = getObjectHeight() * getScaleY();
		drawX = getX() + (getWidth() - drawWidth) / 2;
		drawY = getY() + (getHeight() - drawHeight) / 2;
		batch.draw(frame, drawX, drawY, drawWidth, drawHeight);
	}

	public Rectangle getBound() {
		return new Rectangle(drawX, drawY, drawWidth, drawHeight);
	}

	protected abstract float getObjectWidth();

	protected abstract float getObjectHeight();

	protected abstract StateAction createStateCreate();

	protected abstract StateAction createStateReady();

	protected abstract StateAction createStateFly();

	protected abstract StateAction creatStateAttack();

	public int getPower() {
		return power;
	}

	public float getSpeedx() {
		return speedx;
	}

	public float getSpeedy() {
		return speedy;
	}

	protected void setSpeed(float speedx, float speedy) {
		this.speedx = speedx;
		this.speedy = speedy;
	}

	public void destroy() {
		status = DESTROYED;
		setSpeed(0f, 0f);
	}

	public boolean isReady() {
		return status == READY;
	}

	public boolean isAttacking() {
		return status == FLING;
	}

	public boolean isDestroyed() {
		return status == DESTROYED;
	}
}
